package com.leador.map.location.util;

import android.annotation.SuppressLint;
import android.content.ContentResolver;
import android.content.Context;
import android.location.Location;
import android.location.LocationManager;
import android.provider.Settings;
import android.telephony.CellLocation;
import android.telephony.TelephonyManager;
import android.telephony.gsm.GsmCellLocation;
import android.text.TextUtils;
import android.util.Base64;
import android.util.Log;
import android.widget.Toast;

import org.apache.http.conn.params.ConnManagerParams;
import org.apache.http.params.HttpConnectionParams;
import org.apache.http.params.HttpParams;
import org.json.JSONObject;

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.security.KeyFactory;
import java.security.NoSuchAlgorithmException;
import java.security.PublicKey;
import java.security.cert.CertificateException;
import java.security.spec.InvalidKeySpecException;
import java.security.spec.KeySpec;
import java.security.spec.X509EncodedKeySpec;
import java.util.Arrays;
import java.util.List;
import java.util.zip.GZIPOutputStream;

import com.leador.map.location.Const;
import com.leador.map.location.LocationInfo;
import com.leador.map.location.log.Storage;

public class Utils {
    private Utils() {
        //
    }

    /**
     * 判断两次定位结果变化是否可接受
     *
     * @param locationInfoNow
     * @param locationInfoLast
     * @return boolean
     */
    public static boolean distAccept(LocationInfo locationInfoNow, LocationInfo locationInfoLast) {
        if (locationInfoNow == null || locationInfoLast == null) {
            return true;
        }
        double[] daDist = new double[4];
        daDist[0] = locationInfoNow.getLat();
        daDist[1] = locationInfoNow.getLon();
        daDist[2] = locationInfoLast.getLat();
        daDist[3] = locationInfoLast.getLon();
        float fDist = Utils.distance(daDist);
        Utils.writeCat("net loc dist ", fDist, "m");
        if (fDist <= Const.iMinLoc) {
            float fAccu = locationInfoNow.getAccuracy() - locationInfoLast.getAccuracy();
            if (fAccu <= Const.iMinLoc) {
                Utils.writeCat("dist not accept ", fDist, "#", fAccu);
                return false;
            }
        }
        return true;
    }

    public static void writeCat(Object... oa) {
        if (!Const.bDebug) {
            return;
        }
        StringBuilder sb = new StringBuilder();
        for (Object o : oa) {
            sb.append(o);
        }
        writeCat(sb.toString(), Const.bSaveDebug);
    }

    public static void writeCat(String str, boolean bSaveFile) {
        if (!Const.bDebug) {
            return;
        }
        Log.d(Const.strDebugTag, str);
        if (bSaveFile) {
            Storage.getInstance().writeLog(str);
        }
    }

    public static void toast(Context ctx, String str) {
        if (Const.bDebug) {
            Toast.makeText(ctx, str, Toast.LENGTH_SHORT).show();
            writeCat(str);
        } else if (Const.strSrc.contains("test")) {
            Toast.makeText(ctx, str, Toast.LENGTH_SHORT).show();
            writeCat(str);
        }
    }

    public static int getInt(String str, int defaultValue) {
        int rs = defaultValue;
        try {
            rs = Integer.parseInt(str);
        } catch (Exception e) {
        }
        return rs;
    }
    public static short getShort(String str, short defaultValue) {
        short rs = defaultValue;
        try {
            rs = Short.parseShort(str);
        } catch (Exception e) {
        }
        return rs;
    }
    public static void printE(Throwable t) {
        if (Const.bDebug) {
            t.printStackTrace();
            StackTraceElement[] steArr = t.getStackTrace();
            StringBuilder sb = new StringBuilder();
            for (StackTraceElement ste : steArr) {
                sb.append("@").append(ste.getFileName());
                sb.append(ste.getLineNumber()).append("#");
                sb.append(ste.getClassName()).append("#");
                sb.append(ste.getMethodName());
            }
            writeCat("exception->", sb);
            sb.delete(0, sb.length());
        }
    }

    /**
     * 判断坐标是否在中国境内
     *
     * @param strLon 经度
     * @param strLat strLat
     * @return boolean
     */
    public static boolean coordInCN(String strLon, String strLat) {
        Double dLon = Double.valueOf(strLon);
        Double dLat = Double.valueOf(strLat);
        boolean bInCN = true;
        if (dLon < 73d || dLon > 136d) {
            bInCN = false;
        } else if (dLat < 3d || dLat > 54d) {
            bInCN = false;
        }
        return bInCN;
    }

    /**
     * 判断坐标是否在中国境内
     *
     * @param loc 位置对象
     * @return boolean
     */
    public static boolean coordInCN(Location loc) {
        if (loc == null) {
            return false;
        }
        boolean bInCN = true;
        if (loc.getLongitude() < 73d || loc.getLongitude() > 136d) {
            bInCN = false;
        } else if (loc.getLatitude() < 3d || loc.getLatitude() > 54d) {
            bInCN = false;
        }
        return bInCN;
    }

    /**
     * 将手机信号进行单位换算
     *
     * @param iAsu
     * @return int
     */
    public static int asu2Dbm(int iAsu) {
        return (-113 + 2 * iAsu);
    }

    /**
     * 获取手机MCC和MNC
     *
     * @param tm 电话管理
     * @return String 0-Mcc,1-Mnc
     */
    public static String[] getMccMnc(TelephonyManager tm) {
        String strNetworkOperator = tm.getNetworkOperator();
        String[] saMccMnc = {"", ""};
        if (strNetworkOperator.length() > 4) {
            saMccMnc[0] = strNetworkOperator.substring(0, 3);
            saMccMnc[1] = strNetworkOperator.substring(3, 5);
        } else {
            writeCat("get mcc and mnc error");
        }
        return saMccMnc;
    }

    /**
     * 判断CELLLOCATION是GSM还是CDMA
     *
     * @param cellLoc 基站对象
     * @param ctx     上下文
     * @return int
     */
    public static int getCellType(CellLocation cellLoc, Context ctx) {
        int iType = Const.iDefCellType;
        if (Utils.airPlaneModeOn(ctx)) {
            writeCat("air plane mode is on");
            iType = Const.iDefCellType;
        } else if (cellLoc instanceof GsmCellLocation) {
            iType = Const.iGsmType;
        } else {
            try {
                Class.forName("android.telephony.cdma.CdmaCellLocation");
                iType = Const.iCdmaType;
            } catch (Exception e) {
                Utils.printE(e);
            }
        }
        return iType;
    }

    /**
     * 在JSONOBJECT中，通过指定KEY获取VALUE
     *
     * @param json
     * @return String
     */
    public static String getJSONValue(JSONObject json, String strKey) {
        String strValue = "";
        try {
            strValue = json.getString(strKey);
        } catch (Exception e) {
            writeCat("no value for ", strKey);
        }
        return strValue;
    }

    /**
     * 获取系统时间
     *
     * @return long 系统时间毫秒数
     */
    public static long getTime() {
        return System.currentTimeMillis();
    }

    /**
     * 判断手机是否有GPS PROVIDER
     *
     * @param lm 位置管理器
     * @return boolean 有返回true,没有返回false
     */
    public static boolean hasGPSProvider(LocationManager lm) {
        if (lm == null) {
            return false;
        }
        final List<String> lstProviders = lm.getAllProviders();
        if (lstProviders == null) {
            return false;
        }
        return lstProviders.contains(LocationManager.GPS_PROVIDER);
    }

    /**
     * 判断手机是否有NETWORK PROVIDER
     *
     * @param lm 位置管理器
     * @return boolean 有返回true,没有返回false
     */
    public static boolean hasNetworkProvider(LocationManager lm) {
        if (lm == null) {
            return false;
        }
        final List<String> lstProviders = lm.getAllProviders();
        if (lstProviders == null) {
            return false;
        }
        return lstProviders.contains(LocationManager.NETWORK_PROVIDER);
    }

    /**
     * 判断手机是否进入飞行模式
     *
     * @param ctx 上下文
     * @return boolean 是返回true,否则返回false
     */

    @SuppressLint("InlinedApi")
    @SuppressWarnings("deprecation")
    public static boolean airPlaneModeOn(Context ctx) {
        if (ctx == null) {
            return false;
        }
        int iSdk = android.os.Build.VERSION.SDK_INT;
        ContentResolver cr = ctx.getContentResolver();
        String str = "";
        if (iSdk < 17) {
            str = Settings.System.AIRPLANE_MODE_ON;
            return Settings.System.getInt(cr, str, 0) == 1;
        } else {
            str = Settings.Global.AIRPLANE_MODE_ON;
            return Settings.Global.getInt(cr, str, 0) == 1;
        }
    }

    /**
     * 两点间距离
     *
     * @param coords 坐标数组
     * @return float 粗略的距离运算，单位：米
     */
    public static float distance(double[] coords) {
        if (coords.length != 4) {
            Utils.writeCat("dist error");
            return 0l;
        }
        float[] rs = new float[1];
        Location.distanceBetween(coords[0], coords[1], coords[2], coords[3], rs);
        return rs[0];
    }

    /**
     * 获取服务句柄
     *
     * @param ctx         上下文
     * @param strServName 服务名
     * @return Object 服务对象
     */
    public static Object getService(Context ctx, String strServName) {
        if (ctx == null) {
            return null;
        }
        return ctx.getApplicationContext().getSystemService(strServName);
    }

    /**
     * 将输入流转为字符串
     *
     * @param is
     * @return String
     */
    public static String isToStr(InputStream is) throws Exception {
        int i = -1;
        ByteArrayOutputStream baOutputStream = new ByteArrayOutputStream();
        while ((i = is.read()) != -1) {
            baOutputStream.write(i);
        }
        return baOutputStream.toString();
    }

    /**
     * 设置超时
     *
     * @param httpParams
     * @param iTimeout   超时时间
     * @return
     */
    public static void setTimeOut(HttpParams httpParams, int iTimeout) {
        String CONNECTION_TIMEOUT = HttpConnectionParams.CONNECTION_TIMEOUT;
        httpParams.setIntParameter(CONNECTION_TIMEOUT, iTimeout);
        String SO_TIMEOUT = HttpConnectionParams.SO_TIMEOUT;
        httpParams.setIntParameter(SO_TIMEOUT, iTimeout);
        String TIMEOUT = ConnManagerParams.TIMEOUT;
        httpParams.setLongParameter(TIMEOUT, (long) iTimeout);
    }
    public static String sortParams(String paramString)
    {
        try
        {
            if (TextUtils.isEmpty(paramString)) {
                return "";
            }
            String[] arrayOfString = paramString.split("&");
            Arrays.sort(arrayOfString);
            StringBuffer localStringBuffer = new StringBuffer();
            for (String str : arrayOfString)
            {
                localStringBuffer.append(str);
                localStringBuffer.append("&");
            }
            String strValue = localStringBuffer.toString();
            if (strValue.length() > 1) {
                return (String)strValue.subSequence(0, (strValue.length() - 1));
            }
        }
        catch (Throwable localThrowable)
        {
//            BasicLogHandler.getSDKInfo(localThrowable, "Utils", "sortParams");
        }
        return paramString;
    }
    static PublicKey getPublicKey(Context context)
            throws CertificateException, InvalidKeySpecException, NoSuchAlgorithmException, NullPointerException, IOException
    {
        String str="MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDFoAkykHtfxJJpD9UGIHM6/Z41L9pHlDlFCH10CcVDDRMAP3ilNQBMUFHBGM7qxNsTPGlcpYOOyQ5JaWcpL+EI+dUDmL+rdM6vpvIGIxKIgZv12qntHytheT9xs/ouvooZ6JHu2874Wa981sUqwlr5L8o7ZFc8Dix2CQn4L5Eq8wIDAQAB";
        KeyFactory localKeyFactory = null;
        try
        {
            localKeyFactory = KeyFactory.getInstance("RSA");
            Object localObject1 = new X509EncodedKeySpec(Base64.decode(str, 0));

            return localKeyFactory.generatePublic((KeySpec)localObject1);
        }
        catch (Throwable throwable)
        {
            throwable.printStackTrace();
        }
        return null;
    }
    public static String byte2HexString(byte[] paramArrayOfByte)
    {
        StringBuilder localStringBuilder = new StringBuilder();
        if (paramArrayOfByte == null) {
            return null;
        }
        for (int i = 0; i < paramArrayOfByte.length; i++)
        {
            String str = Integer.toHexString(paramArrayOfByte[i] & 0xFF);
            if (str.length() == 1) {
                str = '0' + str;
            }
            localStringBuilder.append(str);
        }
        return localStringBuilder.toString();
    }
    public static byte[] gZip(byte[] paramArrayOfByte)
    {
        try
        {
            return f(paramArrayOfByte);
        }
        catch (IOException localIOException)
        {
//            BasicLogHandler.getSDKInfo(localIOException, "Utils", "gZip");
        }
        catch (Throwable localThrowable)
        {
//            BasicLogHandler.getSDKInfo(localThrowable, "Utils", "gZip");
        }
        return new byte[0];
    }
    private static byte[] f(byte[] paramArrayOfByte)
            throws IOException, Throwable
    {
        byte[] arrayOfByte = null;
        ByteArrayOutputStream localByteArrayOutputStream = null;
        GZIPOutputStream localGZIPOutputStream = null;
        if (paramArrayOfByte == null) {
            return null;
        }
        try
        {
            localByteArrayOutputStream = new ByteArrayOutputStream();
            localGZIPOutputStream = new GZIPOutputStream(localByteArrayOutputStream);
            localGZIPOutputStream.write(paramArrayOfByte);
            localGZIPOutputStream.finish();
            arrayOfByte = localByteArrayOutputStream.toByteArray();
        }
        catch (IOException localIOException)
        {
            throw localIOException;
        }
        catch (Throwable localThrowable1)
        {
            throw localThrowable1;
        }
        finally
        {
            if (localGZIPOutputStream != null) {
                try
                {
                    localGZIPOutputStream.close();
                }
                catch (Throwable localThrowable2)
                {
                    throw localThrowable2;
                }
            }
            if (localByteArrayOutputStream != null) {
                try
                {
                    localByteArrayOutputStream.close();
                }
                catch (Throwable localThrowable3)
                {
                    throw localThrowable3;
                }
            }
        }
        return arrayOfByte;
    }
    public static byte[] getIV()
    {
        try
        {
            String str1 = "16,16,18,77,15,911,121,77,121,911,38,77,911,99,86,67,611,96,48,77,84,911,38,67,021,301,86,67,611,98,48,77,511,77,48,97,511,58,48,97,511,84,501,87,511,96,48,77,221,911,38,77,121,37,86,67,25,301,86,67,021,96,86,67,021,701,86,67,35,56,86,67,611,37,221,87";

            StringBuffer localStringBuffer = new StringBuffer(str1);
            String str2 = localStringBuffer.reverse().toString();
            String[] arrayOfString1 = str2.split(",");
            byte[] arrayOfByte1 = new byte[arrayOfString1.length];
            for (int i = 0; i < arrayOfString1.length; i++) {
                arrayOfByte1[i] = Byte.parseByte(arrayOfString1[i]);
            }
            byte[] arrayOfByte2 = Encrypt.base64Decode(new String(arrayOfByte1));
            String str3 = new String(arrayOfByte2);
            localStringBuffer = new StringBuffer(str3);
            String str4 = localStringBuffer.reverse().toString();

            String[] arrayOfString2 = str4.split(",");
            byte[] arrayOfByte3 = new byte[arrayOfString2.length];
            for (int j = 0; j < arrayOfString2.length; j++) {
                arrayOfByte3[j] = Byte.parseByte(arrayOfString2[j]);
            }
            return arrayOfByte3;
        }
        catch (Throwable localThrowable)
        {
            BasicLogHandler.a(localThrowable, "Utils", "getIV");
        }
        return new byte[16];
    }
}